package mybatis.plugin;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

import java.util.List;

/**
 * MySQL分页插件
 * Created by src on 2018/6/25.
 */
public class PaginationPlugin extends PluginAdapter {
	/**
	 * 为每个Example类添加limit和offset属性和set、get方法
	 */
	@Override
/*
	public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {

		FullyQualifiedJavaType fullyQualifiedJavaType = FullyQualifiedJavaType.getIntInstance();
		PrimitiveTypeWrapper integerWrapper = fullyQualifiedJavaType.getPrimitiveTypeWrapper();

		Field limit = new Field("limit", fullyQualifiedJavaType);
		limit.setVisibility(JavaVisibility.PRIVATE);
		limit.setType(integerWrapper);
		topLevelClass.addField(limit);

		Method setLimit = new Method("setLimit");
		setLimit.setVisibility(JavaVisibility.PUBLIC);
		setLimit.addParameter(new Parameter(integerWrapper, "limit"));
		setLimit.addBodyLine("this.limit = limit;");
		topLevelClass.addMethod(setLimit);

		Method getLimit = new Method("getLimit");
		getLimit.setVisibility(JavaVisibility.PUBLIC);
		getLimit.setReturnType(integerWrapper);
		getLimit.addBodyLine("return limit;");
		topLevelClass.addMethod(getLimit);

		Field offset = new Field("offset", fullyQualifiedJavaType);
		offset.setVisibility(JavaVisibility.PRIVATE);
		offset.setType(integerWrapper);
		topLevelClass.addField(offset);

		Method setOffset = new Method("setOffset");
		setOffset.setVisibility(JavaVisibility.PUBLIC);
		setOffset.addParameter(new Parameter(integerWrapper, "offset"));
		setOffset.addBodyLine("this.offset = offset;");
		topLevelClass.addMethod(setOffset);

		Method getOffset = new Method("getOffset");
		getOffset.setVisibility(JavaVisibility.PUBLIC);
		getOffset.setReturnType(integerWrapper);
		getOffset.addBodyLine("return offset;");
		topLevelClass.addMethod(getOffset);

		return true;
	}
*/
    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        addLimit(topLevelClass, introspectedTable, "limitStart");
        addLimit(topLevelClass, introspectedTable, "limitLength");
        return super.modelExampleClassGenerated(topLevelClass, introspectedTable);
    }

	/**
	 * 为Mapper.xml的selectByExample添加limit,offset
	 */
	@Override
	public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element,
	                                                                 IntrospectedTable introspectedTable) {
		XmlElement ifLimitNotNullElement = new XmlElement("if");
		ifLimitNotNullElement.addAttribute(new Attribute("test", "limitLength &gt;= 0"));

		XmlElement ifOffsetNotNullElement = new XmlElement("if");
		ifOffsetNotNullElement.addAttribute(new Attribute("test", "limitStart &gt;= 0"));
		ifOffsetNotNullElement.addElement(new TextElement("limit ${limitStart}, ${limitLength}"));
		ifLimitNotNullElement.addElement(ifOffsetNotNullElement);

		XmlElement ifOffsetNullElement = new XmlElement("if");
		ifOffsetNullElement.addAttribute(new Attribute("test", "limitStart == null"));
		ifOffsetNullElement.addElement(new TextElement("limit ${limitLength}"));
		ifLimitNotNullElement.addElement(ifOffsetNullElement);

		element.addElement(ifLimitNotNullElement);

        return super.sqlMapUpdateByExampleWithoutBLOBsElementGenerated(element, introspectedTable);
	}

    private void addLimit(TopLevelClass topLevelClass, IntrospectedTable introspectedTable, String name) {
//        CommentGenerator commentGenerator = context.getCommentGenerator();
        Field field = new Field(name, FullyQualifiedJavaType.getIntInstance());
        field.setVisibility(JavaVisibility.PROTECTED);
        field.setInitializationString("-1");
//        commentGenerator.addFieldComment(field, introspectedTable);
        topLevelClass.addField(field);
        char c = name.charAt(0);
        String camel = Character.toUpperCase(c) + name.substring(1);
        Method method = new Method("set" + camel);
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addParameter(new Parameter(FullyQualifiedJavaType.getIntInstance(), name));
        method.addBodyLine("this." + name + "=" + name + ";");
//        commentGenerator.addGeneralMethodComment(method, introspectedTable);
        topLevelClass.addMethod(method);
        method = new Method("get" + camel);
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setReturnType(FullyQualifiedJavaType.getIntInstance());
        method.addBodyLine("return " + name + ";");
//        commentGenerator.addGeneralMethodComment(method, introspectedTable);
        topLevelClass.addMethod(method);
    }

    public boolean validate(List<String> warnings) {
        return true;
    }
}
